package controllers

import (
	"github.com/astaxie/beego"
	"time"
	"strconv"
	"strings"
	"math/rand"
	"image"
	"os"
	"image/jpeg"
	"image/png"
	"log"
	"github.com/BurntSushi/graphics-go/graphics"
	"fmt"
	"crypto/md5"
	"encoding/hex"
	"net/url"
	"encoding/base64"
	"crypto/hmac"
	"crypto/sha1"
	"github.com/astaxie/beego/cache"
	_ "github.com/astaxie/beego/cache/redis"
	"github.com/garyburd/redigo/redis"
	"github.com/astaxie/beego/httplib"
	"errors"
)

type JsonReturnData_Message struct {
	Code int
	Data string
}

func Json_Message(c *beego.Controller, code int, data string) {
	json_error := JsonReturnData_Message{Code:code, Data:data }
	c.Data["json"] = &json_error
	c.ServeJSON()
	c.StopRun()
}

func Message(c *beego.Controller, redirectURL string, message string, ExtraInfo string, back bool) {
	c.Data["Message"] = message
	c.Data["TargetURL"] = redirectURL
	if back {
		c.Data["script"] = `<script type="text/javascript">
		function back(secs) {
		var jumpTo = document.getElementById('jumpTo');
		jumpTo.innerHTML = secs;
		if (--secs > 0) {
		setTimeout("back(" + secs + ")", 1000);
		}
else {
history.go(-1);
}
}
back(3);
</script>`
	} else {
		c.Data["script"] = fmt.Sprintf(`<script type="text/javascript">
		countDown(3, "%s");
	</script>`, redirectURL)
	}
	c.TplName = "message.html"
	c.Render()
	c.StopRun()
}
func Message_noauto(c *beego.Controller, redirectURL string, message string, ExtraInfo string, back bool) {
	message = strings.Replace(message, "\r\n", "<br>", -1)
	c.Data["Message"] = message
	c.Data["TargetURL"] = redirectURL
	c.Data["script"] = ""
	c.TplName = "message.html"
	c.Render()
	c.StopRun()
}

func RandString(length int) string {
	rand.Seed(time.Now().UnixNano())
	rs := make([]string, length)
	for start := 0; start < length; start++ {
		t := rand.Intn(3)
		if t == 0 {
			rs = append(rs, strconv.Itoa(rand.Intn(10)))
		} else if t == 1 {
			rs = append(rs, string(rand.Intn(26) + 65))
		} else {
			rs = append(rs, string(rand.Intn(26) + 97))
		}
	}
	return strings.Join(rs, "")
}

func RandNum(length int) string {
	rand.Seed(time.Now().UnixNano())
	rs := make([]string, length)
	for start := 0; start < length; start++ {
		rs = append(rs, strconv.Itoa(rand.Intn(10)))
	}
	return strings.Join(rs, "")
}

func GetPassword(passorigin string) string {
	return MD5("dushu"+passorigin+"shuxiang")
}

func MD5(text string) string{
	ctx := md5.New()
	ctx.Write([]byte(text))
	return hex.EncodeToString(ctx.Sum(nil))
}

// LoadImage decodes an image from a file.
func LoadImage_FromPath(path string) (img image.Image, err error) {
	file, err := os.Open(path)
	if err != nil {
		return
	}
	defer file.Close()
	img, _, err = image.Decode(file)
	if err != nil {
		img, err = jpeg.Decode(file)
	}
	return
}

func LodadImage_FromFile(file *os.File) (img image.Image, err error) {
	img,_,err=image.Decode(file)
	if err != nil {
		img, err = jpeg.Decode(file)
	}
	return
}

func SaveImage(path string, img image.Image) (err error) {
	// 需要保存的文件
	imgfile, err := os.Create(path)
	defer imgfile.Close()
	// 以PNG格式保存文件
	err = png.Encode(imgfile, img)
	if err != nil {
		log.Fatal(err)
	}
	return
}

func GenerateTumbnail(filepath string, structName string, Id int64, width int, height int) {
	path := beego.AppConfig.String("uploadspath")
	directory := "/thumbnail/" + strings.ToLower(structName)
	totalPath := path + directory + "/" + strconv.FormatInt(Id, 10) + "_" + strconv.Itoa(width) + "x" + strconv.Itoa(height) + ".png"
	os.MkdirAll(path + directory, 0777)
	src, err := LoadImage_FromPath(filepath)
	if err != nil {
		return
	}
	//height_scale:=width*(src.Bounds().Dy()/src.Bounds().Dx())
	//dst_scale:= image.NewRGBA(image.Rect(0, 0, width, height_scale))

	// 缩略图的大小
	dst := image.NewRGBA(image.Rect(0, 0, width, height))
	// 产生缩略图
	err = graphics.Thumbnail(dst, src)
	if err != nil {
		return
	}
	SaveImage(totalPath, dst)
}
func TacleTumbnail(filepath string, width int, height int) {
	src, err := LoadImage_FromPath(filepath)
	if err != nil {
		return
	}
	//height_scale:=width*(src.Bounds().Dy()/src.Bounds().Dx())
	//dst_scale:= image.NewRGBA(image.Rect(0, 0, width, height_scale))

	// 缩略图的大小
	dst := image.NewRGBA(image.Rect(0, 0, width, height))
	// 产生缩略图
	err = graphics.Thumbnail(dst, src)
	if err != nil {
		return
	}
	SaveImage(filepath, dst)
}
func TacleUeditor(c *beego.Controller) {
	action := c.GetString("action")
	if action == "config" {
		c.Data["json"] = map[string]interface{}{"imageActionName":"uploadimage",
			"imageFieldName":"upfile",
			"imageMaxSize":2048000,
			"imageAllowFiles":[]string{".png",".jpg",".jpeg",".gif",".bmp"},"imageCompressEnable":true,
			"imageCompressBorder":1600,
			"imageInsertAlign":"none",
			"imageUrlPrefix":"",
			"imagePathFormat":"/server/ueditor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","scrawlActionName":"uploadscrawl",
			"scrawlFieldName":"upfile",
			"scrawlPathFormat":"/server/ueditor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","scrawlMaxSize":2048000,
			"scrawlUrlPrefix":"",
			"scrawlInsertAlign":"none",
			"snapscreenActionName":"uploadimage",
			"snapscreenPathFormat":"/server/ueditor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","snapscreenUrlPrefix":"",
			"snapscreenInsertAlign":"none",
			"catcherLocalDomain":[]string{"127.0.0.1","localhost","img.baidu.com"},"catcherActionName":"catchimage",
			"catcherFieldName":"source",
			"catcherPathFormat":"/server/ueditor/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}","catcherUrlPrefix":"",
			"catcherMaxSize":2048000,
			"catcherAllowFiles":[]string{".png",".jpg",".jpeg",".gif",".bmp"},"videoActionName":"uploadvideo",
			"videoFieldName":"upfile",
			"videoPathFormat":"/server/ueditor/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}","videoUrlPrefix":"",
			"videoMaxSize":102400000,
			"videoAllowFiles":[]string{".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid"},"fileActionName":"uploadfile",
			"fileFieldName":"upfile",
			"filePathFormat":"/server/ueditor/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}","fileUrlPrefix":"",
			"fileMaxSize":51200000,
			"fileAllowFiles":[]string{".png",".jpg",".jpeg",".gif",".bmp",".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid",".rar",".zip",".tar",".gz",".7z",".bz2",".cab",".iso",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".pdf",".txt",".md",".xml"},"imageManagerActionName":"listimage",
			"imageManagerListPath":"/server/ueditor/upload/image/",
			"imageManagerListSize":20,
			"imageManagerUrlPrefix":"",
			"imageManagerInsertAlign":"none",
			"imageManagerAllowFiles":[]string{".png",".jpg",".jpeg",".gif",".bmp"},"fileManagerActionName":"listfile",
			"fileManagerListPath":"/server/ueditor/upload/file/",
			"fileManagerUrlPrefix":"",
			"fileManagerListSize":20,
			"fileManagerAllowFiles":[]string{".png",".jpg",".jpeg",".gif",".bmp",".flv",".swf",".mkv",".avi",".rm",".rmvb",".mpeg",".mpg",".ogg",".ogv",".mov",".wmv",".mp4",".webm",".mp3",".wav",".mid",".rar",".zip",".tar",".gz",".7z",".bz2",".cab",".iso",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".pdf",".txt",".md",".xml"}}

		c.ServeJSON()
		c.StopRun()
	}
	if action == "uploadimage" || action == "uploadscrawl" || action=="uploadvideo"{
		return
	}else {
		Json_Message(c, 1, "not surport" + action)
	}
}

func Sendsms(phone string, code string) (error) {
	accessSecret := "psB5TH5p3UDlU6QZlS1nTQGwfABrHQ"
	//accessSecret = "testId"

	Signature := ""
	AccessKeyId := "LTAITq9ckb2pjqQu"
	Action := "SendSms"
	Format := "JSON"
	OutId := "123"
	PhoneNumbers := phone
	RegionId := "cn-hangzhou"
	SignName := "阿里云短信测试专用"
	SignatureMethod := "HMAC-SHA1"
	SignatureNonce := RandString(12)
	SignatureVersion := "1.0"
	TemplateCode := "SMS_80280038"
	TemplateParam := fmt.Sprintf(`{"code":"%s"}`, code)

	Timestamp := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	Version := "2017-05-25"


	sine_url := fmt.Sprintf(`AccessKeyId=%s&Action=%s&Format=%s&OutId=%s&PhoneNumbers=%s&RegionId=%s&SignName=%s&SignatureMethod=%s&SignatureNonce=%s&SignatureVersion=%s&TemplateCode=%s&TemplateParam=%s&Timestamp=%s&Version=%s`, AccessKeyId, Action, Format, OutId, PhoneNumbers, RegionId, SignName, SignatureMethod, SignatureNonce, SignatureVersion, TemplateCode, TemplateParam, Timestamp, Version)
	//sine_url = `AccessKeyId=testId&Action=SendSms&Format=XML&OutId=123&PhoneNumbers=15300000001&RegionId=cn-hangzhou&SignName=阿里云短信测试专用&SignatureMethod=HMAC-SHA1&SignatureNonce=45e25e9b-0a6f-4070-8c85-2956eda1b466&SignatureVersion=1.0&TemplateCode=SMS_71390007&TemplateParam={"customer":"test"}&Timestamp=2017-07-12T02:42:19Z&Version=2017-05-25`
	sine_url=url.PathEscape(sine_url)
	sine_url=strings.Replace(sine_url,":","%3A",-1)

	fmt.Println(sine_url)

	sine_url = "GET&"+getSpecialURLENCODE("/")+"&" + getSpecialURLENCODE(sine_url)
	accessSecretValue:=sign_sha1(accessSecret+"&",sine_url)
	fmt.Println(accessSecretValue)
	Signature=getSpecialURLENCODE(base64.StdEncoding.EncodeToString(accessSecretValue))

	urls := fmt.Sprintf(`http://dysmsapi.aliyuncs.com?Signature=%s&AccessKeyId=%s&Action=%s&Format=%s&OutId=%s&PhoneNumbers=%s&RegionId=%s&SignName=%s&SignatureMethod=%s&SignatureNonce=%s&SignatureVersion=%s&TemplateCode=%s&TemplateParam=%s&Timestamp=%s&Version=%s`, Signature, AccessKeyId, Action, Format, OutId, PhoneNumbers, RegionId, SignName, SignatureMethod, SignatureNonce, SignatureVersion, TemplateCode, TemplateParam, Timestamp, Version)

	fmt.Println(accessSecret)
	fmt.Println(Signature)
	fmt.Println(urls)
	result:=AliSmsReturn{}
	httplib.Get(urls).SetTimeout(5 * time.Second, 5 * time.Second).ToJSON(&result)

	if result.Message=="OK"{
		return nil
	}
	return errors.New("send message wrong"+result.Message)
}

type AliSmsReturn struct {
	Message string
	RequestId string
	BizId string
	Code string
}

func sign_sha1(key string,data string) []byte {
	h := hmac.New(sha1.New, []byte(key))
	h.Write([]byte(data))
	return h.Sum(nil)
}

func getSpecialURLENCODE(sine_url string) string{
	sine_url = url.QueryEscape(sine_url)
	sine_url = strings.Replace(sine_url, "+", "%20", -1)
	sine_url = strings.Replace(sine_url, "*", "%2A", -1)
	sine_url = strings.Replace(sine_url, "%7E", "~", -1)
	return sine_url
}


func PutIntoCache(key string, value string, times time.Duration) error {
	bm, err := cache.NewCache("redis", `{"key":"common","conn":"127.0.0.1:6379","dbNum":"0"}`)
	if err != nil {
		fmt.Println(err)
		return err
	}
	if err = bm.Put(key, value, times); err != nil {
		return err
	}
	return nil
}

func GetCache(key string) (string, error) {
	bm, err := cache.NewCache("redis", `{"key":"common","conn":"127.0.0.1:6379","dbNum":"0"}`)
	if err != nil {
		fmt.Println("redis error"+err.Error())
		return "", err
	}
	v, err := redis.String(bm.Get(key), err)
	return v, err
}

func DeleteCache(key string) {
	bm, _ := cache.NewCache("redis", `{"key":"common","conn":"127.0.0.1:6379","dbNum":"0"}`)
	bm.Delete(key)

}
